home *** CD-ROM | disk | FTP | other *** search
- From: dirk@becker.adviser.com (Dirk Becker)
- Message-ID: <v01530500ad38ee830c96@[194.163.74.11]>
- X-Original-Date: Sat, 3 Feb 1996 17:51:10 +0100
- Path: in1.uu.net!bounce-back
- Date: 03 Feb 96 17:22:11 GMT
- Approved: fjh@cs.mu.oz.au
- Organization: -
- Newsgroups: comp.std.c++
- X-Sender: dirk@194.163.74.12
- Content-Type: text/plain; charset="us-ascii"
- Subject: class.union questions
- X-Auth: PGPMoose V1.1 PGP comp.std.c++
- iQBFAgUBMROZ5uEDnX0m9pzZAQEB1AF/WVxISufM6sQ04fYfOhDI3Fb7rSvzecsv
- +QUvYRtGliDB8QMAlJXz6Noo1sFrdVnl
- =O7qD
-
- Hello, C++ gurus!
-
- In Section 9.6.1 Unions [class.union] there is a large collection of
- restrictions on the union itself and on candidate member classes.
- I would like to ask for reasons of several of them:
-
- a) "A union shall not have base classes. A union shall not be used as
- a base class."
-
- This prevents any construction like the following, where one would
- like to extend the union contained in some base class:
-
- class GenericInterpreter {
- union opcode {
- short tag;
- struct { short tag; short data; } op1;
- struct { short tag; char* data; } op2;
- };
- };
-
- class SpecialInterpreter : public GenericInterpreter {
- union opcode : public GenericInterpreter::opcode {
- struct { short tag; long data; } op3;
- struct { short tag; float data; } op4;
- };
- };
-
- b) "An object of a class with a non-trivial default constructor
- (_class.ctor_), a non-trivial copy constructor (_class.copy_),
- a non-trivial destructor (_class.dtor_), or a non-trivial copy
- assignment operator (_over.ass_, _class.copy_) cannot be a member
- of a union,"
-
- This is a major reduction of the restrictions found in ARM, where all
- kinds of constructors or assignment operators were excluded. Here is
- also a note to give the explanation by the assumption, any member
- functions and especially assignments would usually expect a correctly
- constructed object.
-
- The quoted WP sequence tries its best to exclude virtual function
- tables from the union members, which is just fine. But through the
- non-trivialness you also exclude _any_ custom make of the copy
- constructor and assignment operator.
- So you can have any special assignment operator or constructor for
- your member objects, any but the most common and useful ones.
-
- Another sample:
-
- class longlong { ... };
- struct opcode {
- short tag;
- union {
- short op1;
- long op2;
- longlong op3;
- } data;
- };
-
- If you are lucky to have some native long long datatype, then this
- would be legal code. If you already had to implement your own
- class longlong, now you lost the chance to use it (here).
-
- c) "A union can be thought of as a class"
-
- Here you accept the implications of 12.8.8 and 12.8.13 on implicitly
- defined copy constructor and copy assignment. The already trivial
- copy constructor/assignment of the member objects will then result
- in one large repetition of copies from and to the same memory locations.
- To avoid this behaviour I would strongly recommend to implement your
- own copy constructor or assignment whenever you use a union, because a
- memberwise copy is usually not desired.
-
- Let's combine this with the problems of a) and b):
-
- class GenericInterpreter {
- union opcode {
- opcode(const opcode&); // replace implicitly defined
- opcode& operator = (const opcode&); // memberwise copy versions
-
- short tag;
- struct { short tag; short data; } op1;
- struct { short tag; char* data; } op2;
- };
- };
-
- class SpecialInterpreter : public GenericInterpreter {
- union opcode {
- GenericInterpreter::opcode generic; // error: non-trivial member
- short tag;
- struct { short tag; long data; } op3;
- struct { short tag; float data; } op4;
- };
- };
-
- class ValidInterpreter : public GenericInterpreter {
- union opcode {
- // using copy - paste instead of language features
- short tag;
- struct { short tag; short data; } op1;
- struct { short tag; char* data; } op2;
- //
- struct { short tag; long data; } op3;
- struct { short tag; float data; } op4;
- };
- };
-
- In my opinion, comparing the copy constructor/assignments to others, they
- are only special regarding their use by the implicitly defined memberwise
- copy constructor/assignment by outside classes. Here I can't find a reason
- why a member's custom copy methods should not be applicable instead.
-
- Conclusion, just dreaming:
- I would generally prefer " ... constructors and destructor of member
- objects are ignored, if not explicitly called by the union's ctor/dtor.
- The union's implicit default copy constructor / assignment does a
- binary copy instead of memberwise copy. Objects <containing a vptr>
- cannot be member of a union" - Please pardon my shortcut on vptrs.
-
- d) anonymous union
-
- Why is there no anonymous struct? This is not only for symmetric reasons,
- but anonymous structs inside unions may be as useful as anonymous unions
- inside structs.
-
-
- Best regards
- Dirk
-
- ------------------------------------------------------------------
- Dirk Becker dirk@becker.adviser.com
- Harderweg 76, 22549 Hamburg, Germany Tel. +49 40 80783143
- ---
- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
- Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
- is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
-